/* inspector.js

  Copyright (C) 2006 by Lukas Loehrer
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

  Author: loehrerl [at] gmx [dot] net
*/

// window.Node is not available here
const INode = Components.interfaces["nsIDOMNode"];

const dom_utils = module.require("package", "mozremote/services/browser/dom_util");

function constructor(win, startNode) {
	this._window = win;
	this._currentObject = startNode || win.document;
}

// {{{Remotely callable methods

function reset() {
	this._currentObject = this._window.document;
	return this.getDOMNodeInfo();
}

function getNodeAttributes() {
	var result = {};
	var attrs = this._currentObject.attributes;
	if (attrs != null) {
		for (var i = 0; i < attrs.length; ++i) {
			var a = attrs[i];
			result[a.name] = a.value;
		}
	}
	return result;
}


function getDOMNodeInfo() {
	var result = {};
	var cn = this._currentObject;

	if (!(cn instanceof INode)) {
		result.error = "Not on a DOM node.";
	} else {
		result.type = cn.nodeType;
		result.name = cn.nodeName;
		result.attributes = this.getNodeAttributes();
			result.childNodes = [];
		for (var i = 0; i < cn.childNodes.length; i++) {
			var child = cn.childNodes[i];
			// Skip comments and whitespace-only nodes (preserve preformatted text)
if (dom_utils.is_ignorable(child)) {
				continue;
			}
			var childDetails = this._extractNodeDetails(child);
			childDetails.index = i;
			result.childNodes.push(childDetails);
		}
	}

	return result;
}

const MODE_JS = "js";
const MODE_DOM = "dom";

function changeMode(mode) {
}

function jsInspectAttribute(name) {
}

function jsPrevious() {
}

function domParent() {
	return this._moveInDOM(_ArgGetter("parentNode")) ;
}

function domNthChild(n) {
	var _n = n;
	return this._moveInDOM(function (node) {return node.childNodes[_n]; });
}

function domNextSibling() {
	return this._moveInDOM(_ArgGetter("nextSibling")) ;
}

function domPreviousSibling() {
	return this._moveInDOM(_ArgGetter("previousSibling"));
}

// }}}
// {{{Private methods 

function _extractNodeDetails(node) {
	var result = {
		type: node.nodeType,
		name: node.nodeName
	};
	switch (node.nodeType) {
		case INode.ELEMENT_NODE:
			break;
		case INode.ATTRIBUTE_NODE:
			break;
		case INode.TEXT_NODE:
			result.value = node.nodeValue;
			break;
		case INode.CDATA_SECTION_NODE:
			break;
		case INode.ENTITY_REFERENCE_NODE:
			break;
		case INode.ENTITY_NODE:
			break;
		case INode.PROCESSING_INSTRUCTION_NODE:
			break;
		case INode.COMMENT_NODE:
			break;
		case INode.DOCUMENT_NODE :
			break;
		case INode.DOCUMENT_TYPE_NODE:
			break;
		case INode.DOCUMENT_FRAGMENT_NODE:
			break;
		case INode.NOTATION_NODE:
			break;
		default:
	}
	return result;
}

// This is not a method but a constructor for a helper function
function _ArgGetter(name) {
	var _name = name; // allow closure to access name
	return function (obj) {
		return obj[_name];
	};
}

function _moveInDOM(command) {
	var result = {};
	if (this._currentObject instanceof INode) {
		var target =command(this._currentObject);
		if (target != null) {
			this._currentObject = target;
			result =  this.getDOMNodeInfo();
		} else {
			result.errorMessage = "Movement not possible.";
		}
	} else {
		result.errorMessage = "Not on a DOM node.";
	}
	return result;
}

function _sentinael() {

}

	// }}}


// {{{ Emacs local variables

// local variables:
// folded-file: t
// end:

// }}}
